x86: Intel EPT entry structure changes.
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 4 Feb 2010 09:04:33 +0000 (09:04 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 4 Feb 2010 09:04:33 +0000 (09:04 +0000)
 - Intel SDM defines bit6 in EPT page table entry as "Ignore PAT
   memory type", so change the abbreviation from "igmt" to "ipat".

 - Change the mfn and avail2 fields according to SDM definition.

Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com>
xen/arch/x86/hvm/mtrr.c
xen/arch/x86/mm/hap/p2m-ept.c
xen/include/asm-x86/hvm/vmx/vmx.h
xen/include/asm-x86/mtrr.h

index 8433092a4fb36ad9af79dc7029f9130945fd6a04..efdbe0aa8ab172aee9bf402ac471fc2dc926345c 100644 (file)
@@ -707,13 +707,13 @@ HVM_REGISTER_SAVE_RESTORE(MTRR, hvm_save_mtrr_msr, hvm_load_mtrr_msr,
                           1, HVMSR_PER_VCPU);
 
 uint8_t epte_get_entry_emt(struct domain *d, unsigned long gfn, mfn_t mfn,
-                           uint8_t *igmt, int direct_mmio)
+                           uint8_t *ipat, int direct_mmio)
 {
     uint8_t gmtrr_mtype, hmtrr_mtype;
     uint32_t type;
     struct vcpu *v = current;
 
-    *igmt = 0;
+    *ipat = 0;
 
     if ( (current->domain != d) &&
          ((d->vcpu == NULL) || ((v = d->vcpu[0]) == NULL)) )
@@ -733,7 +733,7 @@ uint8_t epte_get_entry_emt(struct domain *d, unsigned long gfn, mfn_t mfn,
 
     if ( !iommu_enabled )
     {
-        *igmt = 1;
+        *ipat = 1;
         return MTRR_TYPE_WRBACK;
     }
 
@@ -742,7 +742,7 @@ uint8_t epte_get_entry_emt(struct domain *d, unsigned long gfn, mfn_t mfn,
 
     if ( iommu_snoop )
     {
-        *igmt = 1;
+        *ipat = 1;
         return MTRR_TYPE_WRBACK;
     }
 
index ba6e2ee0a91365c36e217cc2c984aab73113ffd5..dacab8c0f00a3693fd92faedfb0fa9308edf67bd 100644 (file)
@@ -105,11 +105,10 @@ static int ept_set_middle_entry(struct domain *d, ept_entry_t *ept_entry)
     page_list_add_tail(pg, &d->arch.p2m->pages);
 
     ept_entry->emt = 0;
-    ept_entry->igmt = 0;
+    ept_entry->ipat = 0;
     ept_entry->sp_avail = 0;
     ept_entry->avail1 = 0;
     ept_entry->mfn = page_to_mfn(pg);
-    ept_entry->rsvd = 0;
     ept_entry->avail2 = 0;
 
     ept_entry->r = ept_entry->w = ept_entry->x = 1;
@@ -186,7 +185,7 @@ ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
     int ret = 0;
     int walk_level = order / EPT_TABLE_ORDER;
     int direct_mmio = (p2mt == p2m_mmio_direct);
-    uint8_t igmt = 0;
+    uint8_t ipat = 0;
     int need_modify_vtd_table = 1;
 
     /* We only support 4k and 2m pages now */
@@ -227,9 +226,9 @@ ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
         if ( mfn_valid(mfn_x(mfn)) || direct_mmio || p2m_is_paged(p2mt) ||
              (p2mt == p2m_ram_paging_in_start) )
         {
-            ept_entry->emt = epte_get_entry_emt(d, gfn, mfn, &igmt,
+            ept_entry->emt = epte_get_entry_emt(d, gfn, mfn, &ipat,
                                                 direct_mmio);
-            ept_entry->igmt = igmt;
+            ept_entry->ipat = ipat;
             ept_entry->sp_avail = order ? 1 : 0;
 
             if ( ret == GUEST_TABLE_SUPER_PAGE )
@@ -253,7 +252,6 @@ ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
             }
 
             ept_entry->avail1 = p2mt;
-            ept_entry->rsvd = 0;
             ept_entry->avail2 = 0;
 
             ept_p2m_type_to_flags(ept_entry, p2mt);
@@ -292,8 +290,8 @@ ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
             split_ept_entry = split_table + i;
             split_ept_entry->emt = epte_get_entry_emt(d, gfn - offset + i,
                                                       _mfn(super_mfn + i),
-                                                      &igmt, direct_mmio);
-            split_ept_entry->igmt = igmt;
+                                                      &ipat, direct_mmio);
+            split_ept_entry->ipat = ipat;
             split_ept_entry->sp_avail =  0;
             /* Don't increment mfn if it's a PoD mfn */
             if ( super_p2mt != p2m_populate_on_demand )
@@ -301,7 +299,6 @@ ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
             else
                 split_ept_entry->mfn = super_mfn; 
             split_ept_entry->avail1 = super_p2mt;
-            split_ept_entry->rsvd = 0;
             split_ept_entry->avail2 = 0;
 
             ept_p2m_type_to_flags(split_ept_entry, super_p2mt);
@@ -309,9 +306,9 @@ ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
 
         /* Set the destinated 4k page as normal */
         split_ept_entry = split_table + offset;
-        split_ept_entry->emt = epte_get_entry_emt(d, gfn, mfn, &igmt,
+        split_ept_entry->emt = epte_get_entry_emt(d, gfn, mfn, &ipat,
                                                   direct_mmio);
-        split_ept_entry->igmt = igmt;
+        split_ept_entry->ipat = ipat;
 
         if ( split_ept_entry->mfn == mfn_x(mfn) )
             need_modify_vtd_table = 0;
@@ -556,16 +553,16 @@ static mfn_t ept_get_entry_current(unsigned long gfn, p2m_type_t *t,
  * return 1 to not to reset ept entry.
  */
 static int need_modify_ept_entry(struct domain *d, unsigned long gfn,
-                                 mfn_t mfn, uint8_t o_igmt, uint8_t o_emt,
+                                 mfn_t mfn, uint8_t o_ipat, uint8_t o_emt,
                                  p2m_type_t p2mt)
 {
-    uint8_t igmt;
+    uint8_t ipat;
     uint8_t emt;
     int direct_mmio = (p2mt == p2m_mmio_direct);
 
-    emt = epte_get_entry_emt(d, gfn, mfn, &igmt, direct_mmio);
+    emt = epte_get_entry_emt(d, gfn, mfn, &ipat, direct_mmio);
 
-    if ( (emt == o_emt) && (igmt == o_igmt) )
+    if ( (emt == o_emt) && (ipat == o_ipat) )
         return 0;
 
     return 1; 
@@ -599,21 +596,21 @@ void ept_change_entry_emt_with_range(struct domain *d, unsigned long start_gfn,
                  * Set emt for super page.
                  */
                 order = EPT_TABLE_ORDER;
-                if ( need_modify_ept_entry(d, gfn, mfn, e.igmt, e.emt, e.avail1) )
+                if ( need_modify_ept_entry(d, gfn, mfn, e.ipat, e.emt, e.avail1) )
                     ept_set_entry(d, gfn, mfn, order, e.avail1);
                 gfn += 0x1FF;
             }
             else
             {
                 /* Change emt for partial entries of the 2m area. */
-                if ( need_modify_ept_entry(d, gfn, mfn, e.igmt, e.emt, e.avail1) )
+                if ( need_modify_ept_entry(d, gfn, mfn, e.ipat, e.emt, e.avail1) )
                     ept_set_entry(d, gfn, mfn, order, e.avail1);
                 gfn = ((gfn >> EPT_TABLE_ORDER) << EPT_TABLE_ORDER) + 0x1FF;
             }
         }
         else /* gfn assigned with 4k */
         {
-            if ( need_modify_ept_entry(d, gfn, mfn, e.igmt, e.emt, e.avail1) )
+            if ( need_modify_ept_entry(d, gfn, mfn, e.ipat, e.emt, e.avail1) )
                 ept_set_entry(d, gfn, mfn, order, e.avail1);
         }
     }
index bf1154eeb948bb681900318ae18a9a072349a815..7cc1f7ffea7100dfb8ac9f45d5ac04ffe44f8af0 100644 (file)
@@ -34,12 +34,11 @@ typedef union {
         w           :   1,
         x           :   1,
         emt         :   3, /* EPT Memory type */
-        igmt        :   1, /* Ignore MTRR memory type */
+        ipat        :   1, /* Ignore PAT memory type */
         sp_avail    :   1, /* Is this a superpage? */
         avail1      :   4,
-        mfn         :   45,
-        rsvd        :   5,
-        avail2      :   2;
+        mfn         :   40,
+        avail2      :   12;
     };
     u64 epte;
 } ept_entry_t;
index 93bfb7ffcd28bce478d4f30534a587323c14244e..0e9e47e2274f9c420ebf7c3be435482c0ce4d568 100644 (file)
@@ -67,7 +67,7 @@ extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
 extern u32 get_pat_flags(struct vcpu *v, u32 gl1e_flags, paddr_t gpaddr,
                   paddr_t spaddr, uint8_t gmtrr_mtype);
 extern uint8_t epte_get_entry_emt(struct domain *d, unsigned long gfn,
-                                  mfn_t mfn, uint8_t *igmt, int direct_mmio);
+                                  mfn_t mfn, uint8_t *ipat, int direct_mmio);
 extern void ept_change_entry_emt_with_range(
     struct domain *d, unsigned long start_gfn, unsigned long end_gfn);
 extern unsigned char pat_type_2_pte_flags(unsigned char pat_type);